#include <iostream>
#include <vector>

#include <boost/type_traits/is_pod.hpp>
#include <boost/mpl/int.hpp>
#include <boost/type_traits/integral_constant.hpp>

template <class T>
struct is_stdvector : boost::false_type {};

template <class T, class Allocator>
struct is_stdvector<std::vector<T, Allocator>> : boost::true_type
{};

namespace detail {
	template <class T, class Tag>
	T process_impl(const T& val, Tag)
	{
		std::cout << "generic version" << std::endl;
		return val;
	}

	template <class T>
	T process_impl(const T& val, boost::mpl::int_<1>)
	{
		std::cout << "1 version" << std::endl;
		return val;
	}

	template <class T>
	T process_impl(const T& val, boost::mpl::int_<4>)
	{
		std::cout << "4 version" << std::endl;
		return val;
	}

	template <class T>
	T process_impl(const T& val, boost::mpl::int_<8>)
	{
		std::cout << "8 version" << std::endl;
		return val;
	}
}

template <class T>
T process(const T& val) {
	static_assert(boost::is_pod<T>::value);
	return detail::process_impl(val, boost::mpl::int_<sizeof(T)>());
}

int main()
{
	
	char a = 1;
	std::cout << "==== 1 ====" << std::endl;
	process(a);
	int b = 2;
	std::cout << "==== 2 ====" << std::endl;
	process(b);
	long c = 3;
	std::cout << "==== 3 ====" << std::endl;
	process(c);
	long long d = 4;
	std::cout << "==== 4 ====" << std::endl;
	process(d);
	std::cout << "==== 5 ====" << std::endl;
	std::cout << std::boolalpha 
		<< "is_stdvector<std::vector<int>>::value:" << is_stdvector<std::vector<int>>::value << "    "
		<< "is_stdvector<int>::value:" << is_stdvector<int>::value << "    "
		<< std::endl;

	return 0;
}